#define _CRT_SECURE_NO_WARNINGS
#include "date_computer.h"
date::date(int year, int month, int day)
	: _year(year),
	_month(month),
	_day(day)
{
	if (_month > 12 || day > get_day(year, month))
	{
		perror("invalid data");
		exit(-1);
	}
}


void date::print() const
{
	std::cout << _year << '/' << _month << '/' << _day<< std::endl;
}

int date::get_day(int year, int month) const
{
	int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
	{
		return 29;
	}
	return arr[month];
}

date date::add_day(int day) const
{
	date tmp(*this);
	tmp._day += day;
	while (tmp._day > get_day(tmp._year, tmp._month))
	{
		tmp._day -= tmp.get_day(tmp._year, tmp._month);
		tmp._month++;
		if (tmp._month == 13)
		{
			tmp._month = 1;
			tmp._year++;
		}
	}
	return tmp;
}

bool date::operator==(const date& d) const
{
	return(_day == d._day &&
		_month == d._month &&
		_year == d._year);
}

bool date::operator!=(const date& d) const
{
	return !((*this) == d);
}

bool date::operator>=(const date& d) const
{
	if (_year < d._year)
	{
		return false;
	}
	else if (_year >= d._year && _month < d._month)
	{
		return false;
	}
	else if (_year >= d._year && _month < d._month && _day < d._day)
	{
		return false;
	}
	return true;
}

bool date::operator>(const date& d) const
{
	return ((*this) >= d) && ((*this) != d);
}

bool date::operator<=(const date& d) const
{
	return !((*this) > d);
}

bool date::operator<(const date& d) const
{
	return ((*this) <= d) && ((*this) != d);
}

// +
date date::operator+(int day) const
{
	date tmp(*this);
	tmp._day += day;
	while (tmp._day > get_day(tmp._year, tmp._month))
	{
		tmp._day -= tmp.get_day(tmp._year, tmp._month);
		tmp._month++;
		if (tmp._month == 13)
		{
			tmp._month = 1;
			tmp._year++;
		}
	}
	return tmp;
}

// +=
date& date::operator+=(int day)
{
	if (day < 0)
	{
		(*this) -= -day;
	}
	else
	{
		_day += day;
		while (_day > get_day(_year, _month))
		{
			_day -= get_day(_year, _month);
			_month++;
			if (_month == 13)
			{
				_month = 1;
				_year++;
			}
		}
	}

	return (*this);
}

//-
date date::operator-(int day) const
{
	date tmp(*this);
	tmp._day -= day;
	while (tmp._day <= 0)
	{
		tmp._month--;
		tmp._day += get_day(tmp._year, tmp._month);
		if (tmp._month == 0)
		{
			tmp._month = 12;
			tmp._year--;
		}
	}
	return tmp;
}

int date::operator-(date& d) const
{
	date tmp(*this);
	while (tmp._year != d._year)
	{
		if(tmp._year < d._year)
		{
			tmp._day -= get_day(tmp._year, tmp._month);
			tmp._month++;
			if (tmp._month == 13)
			{
				tmp._month = 1;
				tmp._year++;
			}
		}
		else if (tmp._year > d._year)
		{
			tmp._month--;
			if (tmp._month == 0)
			{
				tmp._month = 12;
				tmp._year--;
			}
			tmp._day += get_day(tmp._year, tmp._month);

		}
	}
	while (tmp._month != d._month)
	{
		if (tmp._month < d._month)
		{
			tmp._day -= get_day(tmp._month, tmp._month);
			tmp._month++;
			if (tmp._month == 13)
			{
				tmp._month = 1;
				tmp._month++;
			}
		}
		else if (tmp._month > d._month)
		{
			tmp._month--;
			if (tmp._month == 0)
			{
				tmp._month = 12;
				tmp._month--;
			}
			tmp._day += get_day(tmp._month, tmp._month);

		}
	}
	return tmp._day - d._day;
}

//-=
date& date::operator-=(int day)
{
	if (day < 0)
	{
		(*this) += -day;
	}
	else
	{
		_day -= day;
		while (_day <= 0)
		{
			_month--;
			if (_month == 0)
			{
				_month = 12;
				_year--;
			}
			_day += get_day(_year, _month);

		}
	}

	return (*this);
}

// ++ front
date& date::operator++()
{
	_day += 1;
	while (_day > get_day(_year, _month))
	{
		_day -= get_day(_year, _month);
		_month++;
		if (_month == 13)
		{
			_month = 1;
			_year++;
		}
	}
	return (*this);
}

//++ after
date& date::operator++(int)
{
	date tmp(*this);
	_day += 1;
	while (_day > get_day(_year, _month))
	{
		_day -= get_day(_year, _month);
		_month++;
		if (_month == 13)
		{
			_month = 1;
			_year++;
		}
	}
	return tmp;
}
//-